<template>
<div class="calendar">
  <ul class="calendar-week">
    <li v-for="(item, index) in calendarTitleArr" :key="index" class="week-item">
      <span>{{item}}</span>
      {{item.year}}
    </li>
  </ul>

  <ul class="calendar-view relative-position"
      @mousedown="boxStart($event)"
      ref="calendarView">
    <li v-for="(item,index) in calendaArr" :key="index" class="date-view user-select-none  team-item-new"
        @mousedown="isEdit(item)&&setActDay($event, item)"
        :style="{height: calendaArr.length === 42 ? '16.66%' : '20%'}"
        :class="{'weekend': (index+1)%7===0||(index)%7===0,
          'other-month': !isCurrentMonth(item.date),
          'not-edit': !isEdit(item),
          'act-day': isActDay(item.date)}">
      <div class="date-day">
        <div class="num-box">
          <span v-if="isCurrentDay(item.date)" class="num cur-day">今</span>
          <span v-else class="num">{{item.day}}</span>
        </div>

<!--        <q-scroll-area-->
<!--          :thumb-style="thumbStyle"-->
<!--          style="height: 100%; width: 100%; display: flex;justify-content: center"-->
<!--        >-->
        <div class="scrollbar">
          <!--          休息日显示-->
          <div v-if="isRestDay(item)"
               class="rest text-center text-white">
            <q-icon name="iconfont icontubiao-45"></q-icon>
            {{getHolidayTxt(item)}}
            <!--            休息日-->
          </div>
          <!--          有排班模板显示-->
          <ul v-else-if="info[item.year+'-'+item.month+'-'+item.day]&&info[item.year+'-'+item.month+'-'+item.day].shiftsTemplate&&isCurrentMonth(item.date)" class="team-list">
            <li v-for="(shift, shiftIndex) in info[item.year+'-'+item.month+'-'+item.day].shiftsTemplate" :key="shiftIndex" class="team-item">
              <span class="name">{{shift.label}}</span>
              <!--                <span class="value">{{info[item.year+'-'+item.month+'-'+item.day].shifts[shift.value]}}</span>-->
              <span v-if="info[item.year+'-'+item.month+'-'+item.day]&&info[item.year+'-'+item.month+'-'+item.day].shifts[shift.value]&&info[item.year+'-'+item.month+'-'+item.day].shifts[shift.value].team.value!==-1"
                    class="value text-primary">
                    {{info[item.year+'-'+item.month+'-'+item.day].shifts[shift.value].team.label}}
              </span>
<!--              <span v-else class="value text-primary">选择班组</span>-->
            </li>
          </ul>
          <!--          无排班模板显示-->
          <ul v-else-if="isCurrentMonth(item.date)" class="team-list">
            <li v-for="(shift, shiftIndex) in shifts" :key="shiftIndex" class="team-item">
              <span class="name">{{shift.label}}</span>
              <!--                <span class="value">{{info[item.year+'-'+item.month+'-'+item.day].shifts[shift.value]}}</span>-->
              <span v-if="info[item.year+'-'+item.month+'-'+item.day] && info[item.year+'-'+item.month+'-'+item.day].shifts[shift.value]"
                    class="value text-primary">
                    {{info[item.year+'-'+item.month+'-'+item.day].shifts[shift.value].team.label}}
              </span>
<!--              <span v-else class="value text-primary text-new">选择班组</span>-->
            </li>
          </ul>
        </div>
<!--        </q-scroll-area>-->
        <calendar-dialog v-if="isEdit(item)" @setActDay="addActDay" :parent-tab="tab" @changeTab="changeTab"
                         @clearActDay="clearActDay"
                         :shifts="info[item.year+'-'+item.month+'-'+item.day]&&info[item.year+'-'+item.month+'-'+item.day].shiftsTemplate?info[item.year+'-'+item.month+'-'+item.day].shiftsTemplate:shifts" @submit="submit"
                         :itemDay="item" :info="info[item.year+'-'+item.month+'-'+item.day]"></calendar-dialog>
      </div>
    </li>
    <li class="box-select" ref="boxSelect"></li>
  </ul>
</div>
</template>

<script>
import CalendarDialog from './calendar-dialog'
import { mapGetters } from 'vuex'
import { getOffsetLeft, getOffsetTop } from 'src/assets/js/util'

export default {
  name: 'calendar',
  props: {
    curDate: {
      type: Date,
      default () {
        return new Date()
      }
    },
    shifts: {
      type: Array
    },
    info: {},
    shiftsModelId: {
      type: Number || String
    }
  },
  data () {
    return {
      tab: 'holiday',
      calendarTitleArr: [ '星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ], // 星期列表
      actDay: [], // 存储选中的天
      thumbStyle: this.CommonConfig.thumbStyle, // 滚动条样式
      // dateTypeObj: {} // 节日类型
      // 框选用的变量
      mouseTime: null, // 框选用的定时器
      mouseOn: false, // 是否开启框选功能
      startX: 0, // 存放鼠标点击初始位置
      startY: 0,
      parentX: 0,
      parentY: 0,
      isClickEvent: true
    }
  },
  computed: {
    dateTypeObj () {
      let obj = {}
      if (this.dateType && this.dateType.length > 0) {
        this.dateType.forEach(item => {
          obj[item.value] = item.label
        })
      }
      return obj
    },
    // 获取当前时间
    time () {
      const { year, month, day } = this.getYearMonDate(this.curDate)
      return { year, month, day }
    },
    // 当前时间
    curTime () {
      const { year, month, day } = this.getYearMonDate(new Date())
      return { year, month, day }
    },
    // 获取每天数组
    calendaArr () {
      // this.setDateTypeObj()
      const calendaArr = []
      let { year, month } = this.getYearMonDate(new Date(this.time.year, this.time.month, 1))
      // 获取这个月的第一天
      const currentFirstDay = new Date(year, month, 1)

      // 获取当前月第一天星期几
      const weekDay = currentFirstDay.getDay()
      let startTime
      startTime = currentFirstDay.getTime() - (weekDay - 0) * 24 * 60 * 60 * 1000

      let monthDayNum
      if (weekDay === 5 || weekDay === 6) {
        monthDayNum = 42
      } else {
        monthDayNum = 35
      }

      month = Number(month) + 1
      month = month >= 10 ? month : '0' + month
      for (let i = 0; i < monthDayNum; i++) {
        let date = new Date(startTime + i * 24 * 60 * 60 * 1000)
        let day = date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()
        calendaArr.push({
          date: date,
          year: year,
          month: month,
          day: day,
          clickDay: false,
          isSub: date.getDay() === 0
        })
      }
      return calendaArr
    },
    ...mapGetters([
      'dateType'
    ])
  },
  created () {
  },
  methods: {
    // 设置dateTypeObj值
    setDateTypeObj () {
      let obj = {}
      if (this.dateType && this.dateType.length > 0) {
        this.dateType.forEach(item => {
          obj[item.value] = item.label
        })
      }
      this.dateTypeObj = obj
    },
    // 获取给定日期的年月日
    getYearMonDate (date) {
      let year = date.getFullYear()
      let month = date.getMonth()
      let day = date.getDate()
      return { year, month, day }
    },
    // 是否是当前月
    isCurrentMonth (date) {
      let { year: currentYear, month: currentMonth } = this.getYearMonDate(new Date(this.time.year, this.time.month, 1))
      let { year, month } = this.getYearMonDate(date)
      return currentYear === year && currentMonth === month
    },
    // 是否是当天
    isCurrentDay (date) {
      let { year, month, day } = this.getYearMonDate(date)
      return this.curTime.year === year && this.curTime.month === month && this.curTime.day === day
    },
    // 是否是激活状态
    isActDay (date) {
      const index = this.actDay.findIndex(item => {
        return item.date.getTime() === date.getTime()
      })
      return index > -1
    },
    // 添加选中的天
    addActDay (item, event) {
      const index = this.actDay.findIndex(day => {
        return day.date.getTime() === item.date.getTime()
      })
      if (index === -1) {
        if (event.ctrlKey) {
          this.actDay.push(item)
        } else if (event.shiftKey) {
          this.actDay.push(item)
        } else {
          this.actDay = [item]
        }
      }
    },
    // 这一天是否是可编辑的，当前天之前的不可编辑
    isEdit (item) {
      let { year: curYear, month: curMonth, day: CurDay } = this.getYearMonDate(new Date())
      curMonth = curMonth + 1
      let { year, month, day } = this.getYearMonDate(item.date)
      month = month + 1
      return this.isCurrentMonth(item.date) && (curYear < year || (curYear === year && (curMonth < month || (curMonth === month && CurDay <= day))))
    },
    // 是否是休息日
    isRestDay (item) {
      const day = item.year + '-' + item.month + '-' + item.day
      // return this.isCurrentMonth(item.date) && ((!this.info[day] && item.isSub) || (this.info[day] && this.info[day].workStatus !== 'gz'))
      // 去掉周日的默认休息日
      return this.isCurrentMonth(item.date) && (this.info[day] && this.info[day].workStatus !== 'gz')
    },
    // 获取休息日的名称
    getHolidayTxt (item) {
      const day = item.year + '-' + item.month + '-' + item.day
      let exist = this.info[day] && this.dateTypeObj[this.info[day].workStatus]
      return exist ? this.dateTypeObj[this.info[day].workStatus] : '休息日'
    },
    // 设置选中的天
    setActDay (e, item) {
      // 判断是否是鼠标左键被按下
      if (e.button !== 0) return
      if (e.ctrlKey) {
        // 按住ctrl键
        const index = this.actDay.findIndex(day => {
          return day.date.getTime() === item.date.getTime()
        })
        if (index > -1) {
          this.actDay = this.actDay.filter(day => {
            return day.date.getTime() !== item.date.getTime()
          })
        } else {
          this.actDay.push(item)
        }
      } else if (e.shiftKey) {
        // 按住shift键
        if (this.actDay.length === 0) {
          this.actDay.push(item)
        } else {
          let actDays = this.calendaArr.filter(calenda => {
            const condition = (calenda.date >= this.actDay[0].date && calenda.date <= item.date) ||
              (calenda.date <= this.actDay[0].date && calenda.date >= item.date)
            return condition
          })
          this.actDay = actDays
        }
      } else {
        // 单选
        const index = this.actDay.findIndex(day => {
          return day.date.getTime() === item.date.getTime()
        })
        this.actDay = index > -1 ? [] : [item]
      }
    },
    // 清除激活数据
    clearActDay () {
      this.actDay = []
    },
    // 编辑排班
    submit (param) {
      const params = []
      this.actDay.forEach(item => {
        const workDate = `${item.year}-${item.month}-${item.day}`
        param.forEach(i => {
          const paramItem = {
            ...i,
            workDate
          }
          if (!i.shiftsModelId) {
            paramItem.shiftsModeId = this.shiftsModelId
          }
          if (this.info[workDate]) {
            paramItem.id = this.info[workDate].shifts[i.shiftsId].schedulingId
          } else {
            paramItem.id = null
          }
          params.push(paramItem)
        })
      })
      this.$emit('edit', params)
    },
    changeTab (tab) {
      this.tab = tab
    },
    // 框选
    // 鼠标按下事件
    boxStart (event) {
      // this.clearEventBubble(event)
      // 判断鼠标是否是左键按下
      if (event.buttons !== 1 || event.which !== 1) return
      let parentNode = this.$refs.calendarView
      this.parentX = getOffsetLeft(parentNode)
      this.parentY = getOffsetTop(parentNode)
      let self = this
      clearTimeout(this.mouseTime)
      let startTime = new Date()

      // 间隔300毫秒后执行，判断这时候鼠标左键被按住不放
      // this.mouseTime = setTimeout(() => {
      //   this.mouseOn = true
      //   this.startX = event.clientX - this.parentX
      //   this.startY = event.clientY - this.parentY
      //   let boxSelect = this.$refs.boxSelect
      //   boxSelect.style.display = 'block'
      //   boxSelect.style.left = this.startX + 'px'
      //   boxSelect.style.top = this.startY + 'px'
      //   boxSelect.style.width = 0
      //   boxSelect.style.height = 0
      // }, 1300)

      this.mouseOn = true
      this.startX = event.clientX - this.parentX
      this.startY = event.clientY - this.parentY
      let boxSelect = this.$refs.boxSelect
      boxSelect.style.display = 'block'
      boxSelect.style.left = this.startX + 'px'
      boxSelect.style.top = this.startY + 'px'
      boxSelect.style.width = 0
      boxSelect.style.height = 0
      this.$refs.calendarView.onmousemove = function (event) {
        self.boxMove(event)
      }
      this.$refs.calendarView.onmouseup = function (event) {
        self.$refs.calendarView.onmousemove = null
        clearTimeout(this.mouseTime)
        let endTime = new Date()
        if (endTime.getTime() - startTime.getTime() < 200) {
          self.isClickEvent = true
        }
        self.boxStop(event)
      }
    },
    // 鼠标移动事件
    boxMove (event) {
      // 如果框选没有开启。退出
      if (!this.mouseOn) return

      let _x = event.clientX - this.parentX
      let _y = event.clientY - this.parentY
      let boxSelect = this.$refs.boxSelect

      boxSelect.style.left = Math.min(_x, this.startX) + 'px'
      boxSelect.style.top = Math.min(_y, this.startY) + 'px'
      boxSelect.style.width = Math.abs(_x - this.startX) + 'px'
      boxSelect.style.height = Math.abs(_y - this.startY) + 'px'
      this.findNodes(event)
    },
    // 鼠标松开事件
    boxStop (event) {
      this.mouseOn = false
      // this.findNodes()
      let boxSelect = this.$refs.boxSelect
      boxSelect.style.display = 'none'
      boxSelect.style.width = 0
      boxSelect.style.height = 0
    },
    // 获取框选下的元素
    findNodes (event) {
      let dayNodes = document.getElementsByClassName('date-view')
      let boxSelect = this.$refs.boxSelect
      let selectedEls = []
      // 获取框的参数
      let l = boxSelect.offsetLeft
      let t = boxSelect.offsetTop
      let w = boxSelect.offsetWidth
      let h = boxSelect.offsetHeight

      for (let i = 0; i < dayNodes.length; i++) {
        let dayNode = dayNodes[i]
        let sl = dayNode.offsetWidth + dayNode.offsetLeft
        let st = dayNode.offsetHeight + dayNode.offsetTop
        if (sl > l && st > t && dayNode.offsetLeft < l + w && dayNode.offsetTop < t + h) {
          selectedEls.push(this.calendaArr[i])
        }
      }
      let newSelectedEls = []
      selectedEls.forEach(item => {
        if (this.isEdit(item)) {
          newSelectedEls.push(item)
        }
      })
      if (event.ctrlKey || event.shiftKey) {
        this.actDay = this.actDay.concat(newSelectedEls)
      } else {
        this.actDay = newSelectedEls
      }
    }
  },
  components: {
    CalendarDialog
  }
}
</script>

<style scoped lang="stylus">
.calendar{
   display flex
   flex-direction column
   border-radius 6px
   overflow hidden
   .calendar-week{
     flex 68px 0
     display flex
     margin-right -6px
     li.week-item{
       flex 1
       padding-right 6px
       padding-bottom 6px
       height 68px
       color #fff
       font-size 16px
       span{
         display inline-block
         width 100%
         height 100%
         line-height 62px
         background-color $primary
         text-align center
       }
       &:first-child{
         color #F7B82D
         span{
           border-radius:6px 0px 0px 0px;
         }
       }
       &:last-child{
         color #F7B82D
         span{
           border-radius:0px 6px 0px 0px;
         }
       }
     }
   }
   .calendar-view{
     flex 1
     display flex
     flex-wrap wrap
     margin-bottom -6px
     margin-right -6px
     li.date-view{
       flex 14.285% 0
       height 20%
       padding-right 6px
       padding-bottom 6px
       color $primary
       font-size 14px
       position relative
       z-index 10
       .date-day{
         padding 5px 15px
         width 100%
         height 100%
         background-color: rgba(95,119,253,0.1)
         transition all 0.4s
         position relative
         display flex
         flex-direction column
         justify-content center
         align-items center
         .scrollbar{
           height calc(100% - 10px)
           width 100%
           overflow auto
           display flex
           justify-content center
         }
         .num-box{
           width 100%
           height 14px
           text-align left
         }
         .num{
           /*position absolute*/
           /*top 10px*/
           /*left 20px*/
           display inline-block

           line-height 1
         }
         .cur-day{
           width 20px
           height 20px
           line-height 20px
           text-align center
           background-color $primary
           color #fff
           border-radius 50%
         }
       }
       &.weekend{
         color $warning
       }
       &.other-month{
          color #999
         .date-day{
           background-color: rgba(211,211,211,.1)
           cursor: not-allowed
         }
       }
       &.not-edit{
         .team-item-new{
           background #eee
         }
         .text-new{
           color #999 !important
         }
         .date-day{
           cursor: not-allowed
         }
       }
       &.act-day{
         color #fff
         .date-day{
           background-color: rgba(95,119,253,0.7)
           // transform translateY(-4px)
           transform scale(1.02)
           box-shadow:0px 4px 5px 0px rgba(0, 0, 0, 0.25);
         }
       }
     }
     ul.team-list{
       margin 0 auto
       text-align left
       li.team-item{
         font-size 14px
         color #333
       }
       @media screen and (max-width: 1400px) and (min-width: 1000px) {
         li.team-item{
           // padding-left 19px
           padding-left 0px
         }
       }
       @media screen and (max-width: 1600px) and (min-width: 1401px) {
         li.team-item{
           // padding-left 29px
           padding-left 0px
         }
       }
       @media screen and (max-width: 1700px) and (min-width: 1601px) {
         li.team-item{
           // padding-left 29px
           padding-left 0px
         }
       }
       @media screen and (min-width: 1700px) {
         li.team-item{
           // padding-left 46px
           padding-left 0px
         }
       }
       @media screen and (max-height: 800px) and (min-height: 899px) {
         li.team-item{
           // padding-left 46px
           padding-left 0px
         }
         .calendar .rest{
           height 30px
         }
       }
     }
     li.box-select{
       position absolute
       margin 0
       padding 0
       top 0
       left 0
       width 10px
       height 10px
       border 1px dashed $primary
       background-color $primary
       z-index 1000
       opacity 0.6
       display none
     }
   }
  /*休息日*/
  .rest{
    margin 0 auto
    width 100%
    max-width 150px
    height 45px
    line-height 39px
    background-color #44d8c6
    border 3px solid #ffffff
    border-radius 22px
  }
 }
@media all and (min-height: 800px) and (max-height: 899px) {
  li.team-item{
    padding-left 47px
  }
  .calendar .rest{
    height 35px
    line-height 29px
  }
}
@media all and (min-height: 900px) and (max-height: 949px) {
  .calendar .rest{
    height 40px
    line-height 34px
  }
}
@media all and (min-height: 950px) and (max-height: 999px) {
  .calendar .rest{
    height 43px
    line-height 37px
  }
}
@media all and (min-height: 1000px) {
  .calendar .rest{
    line-height 39px
    height 45px
  }
}
</style>
